package minioTool

import (
	"bytes"
	"context"
	"fmt"
	"github.com/minio/minio-go/v7"
	"github.com/minio/minio-go/v7/pkg/credentials"
	"go.uber.org/zap"
	"strconv"
)

const (
	Album = "albumBucket"
)

type MinioClient struct {
	c *minio.Client
}

func (c *MinioClient) Put(
	ctx context.Context,
	bucketName string,
	fileName string,
	data []byte,
	size int64,
	contentType string,
) (minio.UploadInfo, error) {
	object, err := c.c.PutObject(
		ctx,
		bucketName,
		fileName,
		bytes.NewBuffer(data),
		size,
		minio.PutObjectOptions{ContentType: contentType},
	)
	return object, err
}
func (c *MinioClient) Compose(
	ctx context.Context,
	bucketName string,
	fileName string,
	totalChunks int,
) (minio.UploadInfo, error) {
	dst := minio.CopyDestOptions{
		Bucket: bucketName,
		Object: fileName,
	}
	var srcs []minio.CopySrcOptions
	for i := 1; i <= totalChunks; i++ {
		formatInt := strconv.FormatInt(int64(i), 10)
		src := minio.CopySrcOptions{
			Bucket: bucketName,
			Object: fileName + "_" + formatInt,
		}
		srcs = append(srcs, src)
	}
	object, err := c.c.ComposeObject(
		ctx,
		dst,
		srcs...,
	)
	return object, err
}
func New(endpoint, accessKey, secretKey string, useSSL bool) (*MinioClient, error) {
	minioClient, err := minio.New(endpoint, &minio.Options{
		Creds:  credentials.NewStaticV4(accessKey, secretKey, ""),
		Secure: useSSL,
	})
	return &MinioClient{c: minioClient}, err
}
func NewMinio() (*MinioClient, error) {
	client, err := minio.New("192.168.2.9:9009",
		&minio.Options{
			Creds:  credentials.NewStaticV4("Z4BBxdGcLEDqXEzsUAVn", "HZTR9ng3sJAgjSMttgoBs3m1psilB1Q78knP4iwK", ""),
			Secure: false,
		})
	if err != nil {
		zap.L().Error(fmt.Sprintf("minio客户端初始化失败:%v", err), zap.Error(err))
		panic(err)
	}
	return &MinioClient{c: client}, nil
}

// UploadFile 上传文件
func (m MinioClient) UploadFile(bucketName string, objectName string, filePath string) error {
	ctx := context.Background()
	contentType := "application/octet-stream"
	info, err := m.c.FPutObject(ctx, bucketName, objectName, filePath, minio.PutObjectOptions{ContentType: contentType})
	if err != nil {
		zap.L().Error(fmt.Sprintf("%s上传minio的%s系统失败:%v", objectName, bucketName, err), zap.Error(err))
		return err
	}
	zap.L().Info(fmt.Sprintf("Successfully uploaded %s of size %d\n", objectName, info.Size))
	return nil
}
func (m MinioClient) MakeBucket(bucketName string) error {
	// Make a new bucket called testbucket.
	ctx := context.Background()
	// 判断桶是否存在
	exists, err := m.c.BucketExists(ctx, bucketName)
	if err != nil {
		zap.L().Error("查询桶失败", zap.Error(err))
		return err
	}
	if exists {
		return nil
	}
	location := "us-east-1"
	err = m.c.MakeBucket(ctx, bucketName, minio.MakeBucketOptions{Region: location})
	if err != nil {
		// Check to see if we already own this bucket (which happens if you run this twice)
		exists, errBucketExists := m.c.BucketExists(ctx, bucketName)
		if errBucketExists == nil && exists {
			zap.L().Info(fmt.Sprintf("We already own %s\n", bucketName))
			return err
		} else {
			zap.L().Error(fmt.Sprintf("创建桶失败error:%v", err), zap.Error(err))
			return err
		}
	} else {
		zap.L().Info(fmt.Sprintf("Successfully created %s\n", bucketName))
	}
	return nil
}
